
/**
 * tinyurlapi.h
 * 
 * TinyUrlAPI is a wrapper of tinyurl API
 * 
 * Copyright (c) 2008 Harunobu Oyama <nobukichi at gmail.com>
 * Licensed under GNU GPL version 3
 *
 */

#ifndef		TINYURL_API_INCLUDED
#define		TINYURL_API_INCLUDED

#include <boost/shared_ptr.hpp>
#include <QHttp>
#include <QBuffer>
#include "tweet.h"

class TinyUrlAPI : public QObject
{
	Q_OBJECT
		
public:
	explicit TinyUrlAPI(QObject* parent = 0);

	~TinyUrlAPI();
	
	//! send a request to tinyurl-encode a url
	//! the result of this function will be asynchronously reported by signalEncodeFinished
	void requestEncode(const QString& orgUrl);

	//! send a request to decode a tinyurl-encoded url
	//! the result of this function will be asynchronously reported by signalDecodeFinished
	void requestDecode(const QString& tinyUrl);

	//! reset all the request before exiting.
	void reset();

signals:
	//! signal to report a http error 
	void signalDetectedHttpError(QHttp::Error error);

	//! signal to report the result of encode request
	void signalEncodeFinished(const QString& orgUrl, const QString& tinyUrl);

	//! signal to report the result of decode request
	void signalDecodeFinished(const QString& tinyUrl, const QString& orgUrl);
	
private:
	//! disallow copy/assign TinyUrlAPI instance
	TinyUrlAPI(const TinyUrlAPI&);
	TinyUrlAPI& operator=(const TinyUrlAPI&);

	//! TinyUrlAPI request object
	class Request {
	public:
		enum Type {
			REQ_TYPE_NIL,
			REQ_TYPE_ENCODE,
			REQ_TYPE_DECODE,
		};
		
		explicit Request(Type type = REQ_TYPE_NIL, const QString& info = "");
		Type type() const;
		QBuffer* responseBuffer();
		QString extraInfo() const;
		
	private:
		Type reqType;
		QString extra;
		boost::shared_ptr<QBuffer> ptrResponseBuffer;
	};
	
	//! send a GET request to tinyurl.com with the given path
	void sendGetRequest(const QString& path, Request::Type reqType, const QString& extra = QString());

	QHttp http; //! http engine associated with tinyurl.com
	
	typedef std::map<int, Request> RequestMap;
	RequestMap activeRequests; //! map from request id returned by QHttp to Request object holding a QBuffer to receive the http response

	typedef std::map<QString, QString> DecodeCache; 
	DecodeCache decodeCache; //! never decode the known tinyurl twice
	
private slots:
	//! slot to receive http response from QHttp
	void slotRequestFinished(int id, bool error);
};

#endif	//	TINYURL_API_INCLUDED

